#!/usr/bin/env node

const { program } = require('commander');
const fs = require('fs-extra');
const path = require('path');
const chalk = require('chalk');
const PQueue = require('p-queue').default;
const readline = require('readline');

const { extractEpub, processImagePaths } = require('./utils/epubParser');
const { convertHtmlToPdf, convertToBothVersions, closeBrowser } = require('./converters/pdfConverter');

// 版本信息
const packageJson = require('./package.json');
program.version(packageJson.version);

// 全局配置
const MAX_CONCURRENT = 3;
const queue = new PQueue({ concurrency: MAX_CONCURRENT });

// 启动LOGO和版本号
console.log(chalk.cyan(`\n==============================`));
console.log(chalk.cyan(`🍄 鸡枞 EPUB 转 PDF CLI v${packageJson.version}`));
console.log(chalk.cyan(`==============================\n`));

/**
 * 转换单个 EPUB 文件
 */
async function convertEpubFile(epubPath, outputDir, options = {}) {
  const startTime = Date.now();
  const epubName = path.basename(epubPath, '.epub');
  
  try {
    console.log(chalk.blue(`\n📚 开始转换: ${path.basename(epubPath)}`));
    
    // 1. 创建临时解压目录
    const tempDir = path.join(outputDir, `temp_${epubName}_${Date.now()}`);
    console.log(chalk.gray(`📁 创建临时目录: ${path.basename(tempDir)}`));
    
    // 2. 解压 EPUB 文件
    console.log(chalk.gray('📦 解压 EPUB 文件...'));
    const { extractDir, htmlFiles, images } = await extractEpub(epubPath, tempDir);
    
    if (htmlFiles.length === 0) {
      throw new Error('未找到任何 HTML 章节文件');
    }
    
    console.log(chalk.green(`✅ 找到 ${htmlFiles.length} 个章节文件`));
    if (images.length > 0) {
      console.log(chalk.green(`✅ 找到 ${images.length} 个图片文件`));
      
      // 统计实际存在的图片文件数量
      const imagesDir = path.join(extractDir, 'images');
      if (await fs.pathExists(imagesDir)) {
        const imageFiles = await fs.readdir(imagesDir);
        const actualImageCount = imageFiles.filter(file => 
          /\.(jpg|jpeg|png|gif|bmp|webp|svg)$/i.test(file)
        ).length;
        console.log(chalk.cyan(`📊 实际图片文件: ${actualImageCount} 张`));
      }
    }
    
    // 3. 处理 HTML 文件中的图片路径
    console.log(chalk.gray('🖼️  处理图片路径...'));
    const processedHtmlFiles = [];
    for (const htmlFile of htmlFiles) {
      const fullPath = path.join(extractDir, htmlFile);
      let htmlContent = await fs.readFile(fullPath, 'utf8');
      
      // 处理图片路径 - 只处理一次
      htmlContent = processImagePaths(htmlContent, fullPath, extractDir);
      
      // 保存处理后的 HTML 文件
      const processedPath = fullPath.replace('.html', '_processed.html').replace('.xhtml', '_processed.xhtml');
      await fs.writeFile(processedPath, htmlContent, 'utf8');
      processedHtmlFiles.push(processedPath);
    }
    
    // 4. 创建输出目录
    const pdfOutputDir = path.join(outputDir, 'pdf');
    await fs.ensureDir(pdfOutputDir);
    
    // 5. 转换 PDF
    console.log(chalk.gray('📄 开始生成 PDF...'));
    const conversionStartTime = Date.now();
    
    let result;
    if (options.compress) {
      // 生成高清版和压缩版
      result = await convertToBothVersions(processedHtmlFiles, pdfOutputDir, epubName, {
        format: 'A4',
        printBackground: true,
        margin: { top: '1cm', right: '1cm', bottom: '1cm', left: '1cm' }
      });
      
      const conversionTime = ((Date.now() - conversionStartTime) / 1000).toFixed(2);
      console.log(chalk.green(`✅ PDF 生成完成 (耗时: ${conversionTime}s)`));
      
      // 获取文件大小信息
      const hdStats = await fs.stat(result.hdPath);
      const compressedStats = await fs.stat(result.compressedPath);
      
      console.log(chalk.cyan(`📊 文件大小信息:`));
      console.log(chalk.cyan(`   高清版: ${(hdStats.size / 1024 / 1024).toFixed(2)} MB`));
      console.log(chalk.cyan(`   压缩版: ${(compressedStats.size / 1024 / 1024).toFixed(2)} MB`));
      console.log(chalk.cyan(`   压缩率: ${((1 - compressedStats.size / hdStats.size) * 100).toFixed(1)}%`));
      
    } else {
      // 只生成高清版
      const pdfPath = path.join(pdfOutputDir, `${epubName}.pdf`);
      await convertHtmlToPdf(processedHtmlFiles, pdfPath, {
        format: 'A4',
        printBackground: true,
        margin: { top: '1cm', right: '1cm', bottom: '1cm', left: '1cm' }
      });
      
      const conversionTime = ((Date.now() - conversionStartTime) / 1000).toFixed(2);
      console.log(chalk.green(`✅ PDF 生成完成 (耗时: ${conversionTime}s)`));
      
      const stats = await fs.stat(pdfPath);
      console.log(chalk.cyan(`📊 文件大小: ${(stats.size / 1024 / 1024).toFixed(2)} MB`));
      
      result = { hdPath: pdfPath };
    }
    
    // 6. 清理临时文件
    console.log(chalk.gray('🧹 清理临时文件...'));
    await fs.remove(tempDir);
    
    const totalTime = ((Date.now() - startTime) / 1000).toFixed(2);
    console.log(chalk.green(`🎉 转换完成! 总耗时: ${totalTime}s`));
    
    return result;
    
  } catch (error) {
    console.error(chalk.red(`❌ 转换失败: ${error.message}`));
    throw error;
  }
}

/**
 * 批量转换目录中的 EPUB 文件
 */
async function convertEpubDirectory(inputDir, outputDir, options = {}) {
  try {
    console.log(chalk.blue(`\n📁 扫描目录: ${inputDir}`));
    
    // 查找所有 EPUB 文件
    const files = await fs.readdir(inputDir);
    const epubFiles = files.filter(file => 
      file.toLowerCase().endsWith('.epub')
    ).map(file => path.join(inputDir, file));
    
    if (epubFiles.length === 0) {
      console.log(chalk.yellow('⚠️  目录中没有找到 EPUB 文件'));
      return;
    }
    
    console.log(chalk.green(`✅ 找到 ${epubFiles.length} 个 EPUB 文件`));
    
    // 创建输出目录
    await fs.ensureDir(outputDir);
    
    // 批量转换
    const results = [];
    const startTime = Date.now();
    
    for (let i = 0; i < epubFiles.length; i++) {
      const epubFile = epubFiles[i];
      console.log(chalk.blue(`\n[${i + 1}/${epubFiles.length}] 处理: ${path.basename(epubFile)}`));
      
      try {
        const result = await convertEpubFile(epubFile, outputDir, options);
        results.push({ file: epubFile, success: true, result });
      } catch (error) {
        console.error(chalk.red(`❌ 转换失败: ${path.basename(epubFile)}`));
        results.push({ file: epubFile, success: false, error: error.message });
      }
    }
    
    const totalTime = ((Date.now() - startTime) / 1000).toFixed(2);
    const successCount = results.filter(r => r.success).length;
    
    console.log(chalk.blue(`\n📊 批量转换完成!`));
    console.log(chalk.green(`✅ 成功: ${successCount}/${epubFiles.length}`));
    console.log(chalk.red(`❌ 失败: ${epubFiles.length - successCount}/${epubFiles.length}`));
    console.log(chalk.cyan(`⏱️  总耗时: ${totalTime}s`));
    
    return results;
    
  } catch (error) {
    console.error(chalk.red(`❌ 批量转换失败: ${error.message}`));
    throw error;
  }
}

/**
 * 交互式转换模式
 */
async function interactiveMode() {
  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  });
  const question = (prompt) => new Promise((resolve) => rl.question(prompt, resolve));
  try {
    console.log(chalk.blue('🎯 交互式 EPUB 转 PDF 工具'));
    console.log(chalk.gray('输入 "q"、"quit" 或 "exit" 退出\n'));
    while (true) {
      const input = await question(chalk.cyan('请输入 EPUB 文件路径或目录路径: '));
      if (["q","quit","exit"].includes(input.trim().toLowerCase())) {
        console.log(chalk.blue('👋 再见!'));
        break;
      }
      if (!input.trim()) {
        console.log(chalk.yellow('⚠️  请输入有效路径'));
        continue;
      }
      const inputPath = path.resolve(input.trim());
      if (!await fs.pathExists(inputPath)) {
        console.log(chalk.red('❌ 文件或目录不存在'));
        continue;
      }
      const stats = await fs.stat(inputPath);
      const isDirectory = stats.isDirectory();
      const compressAnswer = await question(chalk.cyan('是否生成压缩版? (y/N): '));
      const compress = ["y","yes"].includes(compressAnswer.trim().toLowerCase());
      let outputDir;
      if (isDirectory) {
        outputDir = path.join(inputPath, 'pdf_output');
      } else {
        outputDir = path.join(path.dirname(inputPath), 'pdf_output');
      }
      try {
        if (isDirectory) {
          await convertEpubDirectory(inputPath, outputDir, { compress });
        } else {
          await convertEpubFile(inputPath, outputDir, { compress });
        }
        console.log(chalk.green(`\n📁 输出目录: ${outputDir}`));
      } catch (error) {
        console.error(chalk.red(`❌ 转换失败: ${error.message}`));
      }
      console.log(chalk.gray('\n' + '='.repeat(50) + '\n'));
    }
  } finally {
    rl.close();
  }
}

// 命令行参数配置
program
  .name('epub-to-pdf')
  .description('将 EPUB 文件转换为 PDF 格式')
  .option('-o, --output <dir>', '输出目录', './pdf_output')
  .option('-c, --compress', '生成高清版和压缩版两个版本')
  .option('-i, --interactive', '交互式模式');

program
  .argument('[input]', 'EPUB 文件路径或包含 EPUB 文件的目录路径')
  .action(async (input, options) => {
    try {
      // 如果没有提供输入参数，进入交互模式
      if (!input) {
        await interactiveMode();
        return;
      }
      
      const inputPath = path.resolve(input);
      
      if (!await fs.pathExists(inputPath)) {
        console.error(chalk.red(`❌ 文件或目录不存在: ${input}`));
        process.exit(1);
      }
      
      const stats = await fs.stat(inputPath);
      const isDirectory = stats.isDirectory();
      
      if (isDirectory) {
        await convertEpubDirectory(inputPath, options.output, { compress: options.compress });
      } else {
        await convertEpubFile(inputPath, options.output, { compress: options.compress });
      }
      
      console.log(chalk.green(`\n📁 输出目录: ${path.resolve(options.output)}`));
      
    } catch (error) {
      console.error(chalk.red(`❌ 转换失败: ${error.message}`));
      process.exit(1);
    } finally {
      // 关闭浏览器
      await closeBrowser();
    }
  });

// 处理未捕获的异常
process.on('uncaughtException', (error) => {
  console.error(chalk.red(`❌ 未捕获的异常: ${error.message}`));
  process.exit(1);
});

process.on('unhandledRejection', (reason, promise) => {
  console.error(chalk.red(`❌ 未处理的 Promise 拒绝: ${reason}`));
  process.exit(1);
});

// 优雅退出
process.on('SIGINT', async () => {
  console.log(chalk.yellow('\n⚠️  正在关闭...'));
  await closeBrowser();
  process.exit(0);
});

// 解析命令行参数
program.parse(); 